package GBP;

import java.io.*;
import java.util.*;

/**
 * GraphDef.java
 * Created: 2005-12-22 10:30
**/

/**
 * This class defines the graph
 * for the Graph-Bipartitioning-Problem.
 *
 * @author T.S.Yo
**/

public class GraphDef {
	public String gName;            // Graph name
	public GraphNode[] graph;       // Array of nodes
	
//---------------------------------------------------------------------
// Constructor    
	/** Full-parameter constructor **/
	public GraphDef( String name, int size ) {
        this.gName = name;
		this.graph = new GraphNode[size];
	}

	/** Constructor uses default array length **/
	public GraphDef() {
        this.gName = "Graph";
		this.graph = new GraphNode[500];
	}
//---------------------------------------------------------------------
// Overriding toString() to show the GraphNode
	public String toString() {
		String result = "    " + gName + "\n";
		for(int i = 0; i < graph.length; i++){
			result = result + graph[i].toString() + "\n";
		}		
		return result;
	}	
//---------------------------------------------------------------------
// Methods to read a graph from a ASCII file 
    public void ReadGBP(final String fName){
        try
        {
            int i = 0;
            String line;
            BufferedReader br = new BufferedReader(new FileReader(fName));         
            while ((line = br.readLine()) != null) {
                //System.out.println(line);       // For testing
                graph[i] = parseLine(line);
                //System.out.println(graph[i]);   // For testing
                i++;
            }
            br.close();
            br = null;       
        } catch (java.io.FileNotFoundException ex) {
            System.out.println("!!!    File '" + fName + "' does not exist    !!!");
        } catch (java.io.IOException ex) {
            ex.printStackTrace();
        } 
    }

    /** Parse each line of the data set into a node of the graph **/
    public GraphNode parseLine(final String line){
        // Parameters for GraphNode
        int nodeID;
        double[] position = new double[2];
        int nNeighbors;
        int[] neighbors;
        
        // Tokenize the node data
        StringTokenizer st = new StringTokenizer(line, ", ()");
        
        // 1st token: node ID
        String token = st.nextToken();
        nodeID = Integer.parseInt(token);
        // 2nd token: node position X
        token = st.nextToken();
        position[0] = Double.parseDouble(token);
        // 3rd token: node position Y
        token = st.nextToken();
        position[1] = Double.parseDouble(token);
        // 4th token: # of neighbors
        token = st.nextToken();
        nNeighbors = Integer.parseInt(token);
        // Read neighbors
        neighbors = new int[nNeighbors];
        for (int i = 0; i < nNeighbors; i++){
            if(st.hasMoreTokens()){
                token = st.nextToken();
                neighbors[i] = Integer.parseInt(token);
            } else {
                System.out.println("!!!    # of Neighbors not match    !!!");
            }
        }
        GraphNode node = new GraphNode(nodeID,position,neighbors);
        return node;
    }
}
